﻿using System.ComponentModel.Composition;
using System.Text;
using PowerGui.AddOn.Interfaces;
using Quest.PowerGUI.ScriptEditor;
using Quest.PowerGUI.ScriptEditor.Shared;
using System.Windows.Forms;
using ActiproSoftware.SyntaxEditor;
using System;

namespace PowerGui.AddOn.Impl
{
    [Export(typeof(IScriptEditor))]
    public class PsControlWrapper : PSSyntaxEditorControl, IScriptEditor
    {
        private readonly IPowerGui _powerGui;
        private IEditorFontAndColors _fontsAndColors;

        public PsControlWrapper( IPowerGui powerGui, IDebugger debug)
        {
            _powerGui = powerGui;

            Id = Guid.NewGuid();

            this.AutoCheckSyntax = true;
            this.Dock = DockStyle.Fill;
            this.Document = new Document();
            this.ReadOnly = false;
            this.Script = null;
            this.BracketHighlightingVisible = true;
            this.Document.LineModificationMarkingEnabled = true;
            IndicatorMarginBreakPointsOnClick = true;
            this.WordWrapping = false;
            this.Font = EditorSettings.Instance.Font;
            this.LineNumbering = EditorSettings.Instance.ViewLineNumbers;
            _fontsAndColors = new EditorFontsAndColors(this);

            this.GotFocus += _psControl_GotFocus;

            var debugger = debug as PowerShellDebugger;

            ToggleBreakpoint += delegate(object s, ToggleBreakpointEventArgs e)
            {
                debugger.Debugger.PSSyntaxEditorControl_ToggleBreakpoint(e.Editor, e.Offset, e.SimpleAlgorithm);
            };

            DocumentIndicatorRemoved += delegate(object s, IndicatorEventArgs e)
            {
                debugger.Debugger.PSSyntaxEditorControl_DocumentIndicatorRemoved(s, e.Indicator);
            };

            DocumentIndicatorResized += delegate(object s, IndicatorEventArgs e)
            {
                debugger.Debugger.PSSyntaxEditorControl_DocumentIndicatorResized(s, e.Indicator);
            };

            DocumentIndicatorAdded += delegate(object s, IndicatorEventArgs e)
            {
                debugger.Debugger.PSSyntaxEditorControl_DocumentIndicatorAdded(s, e.Indicator);
            };

            Initialize();
        }

        public new void Initialize()
        {
            base.Initialize();

            var syntaxFile = System.IO.Path.Combine(_powerGui.InstallPath, "PowerShellSyntax.xml");

            this.Document.LoadLanguageFromXml(syntaxFile, 0);
        }

        public void ShowSnippetSelector()
        {
            if (!this.ReadOnly)
            {
                base.Document.GetWordText(base.Caret.Offset);
                //try
                //{
                    var csn = new CodeSnippetFolder("Root", System.IO.Path.Combine(_powerGui.InstallPath, "snippets"));
                    base.IntelliPrompt.CodeSnippets.ShowInsertSnippetPopup(base.Caret.Offset,
                        "Insert snippet", csn, CodeSnippetTypes.Expansion);
                //}
                //catch
                //{
                //}
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.Control && !e.Alt && e.KeyCode == Keys.I)
            {
                ShowSnippetSelector();
            }
            else
            {
                base.OnKeyDown(e);
            }
        }

        void _psControl_GotFocus(object sender, EventArgs e)
        {
            _powerGui.Debugger.CurrentEditor = this;
        }


        public Guid Id
        {
            get; private set;
        }

        public string FileName
        {
            get
            {
                return Document.Filename;
            }
        }

        public Encoding DocumentEncoding { get; set; }

        public void LoadFile(string filename)
        {
            DocumentEncoding = base.LoadFile(filename);
        }

        public void SaveFile()
        {
            base.SaveFile(DocumentEncoding, true);
        }

        public void SaveFile(string filename)
        {
            base.SaveFile(filename, DocumentEncoding);
        }

        public Control EditorControl
        {
            get
            {
                return this;
            }
        }

        public void ShowPrintDialog()
            {
            PSSyntaxEditorControl se = this.EditorControl as PSSyntaxEditorControl;
            se.Print();
            }

        public void ShowPageSetupForm()
            {
            PSSyntaxEditorControl se = this.EditorControl as PSSyntaxEditorControl;
            se.ShowPageSetupForm(se);
            }

        /// <summary>
        /// 
        /// </summary>
        public IEditorFontAndColors FontAndColors
        {
            get { return _fontsAndColors; }
        }
    }
}
